'use strict';
import React, { useEffect, useState, useRef } from 'react';
import { Checkbox, Form, Input, Select } from 'antd';
import { layout } from '../conf';
import styles from './index.less';


/*
* 组件注释
* create by wuqiong
* creation time 2022/04/25
* 多实例
* */
const { Option } = Select;
const getOption = (isShow) => {
  return isShow
    ? [
      { label: '异步前', value: 'asyncBefore' },
      { label: '异步后', value: 'asyncAfter' },
      { label: '排除', value: 'exclusive' }
    ]
    : [
      { label: '异步前', value: 'asyncBefore' },
      { label: '异步后', value: 'asyncAfter' },
    ]
}
const Index = (props) => {
  const { businessObject, type, prefix } = props;
  const [defaultLoopInstanceForm] = useState({
    loopCharacteristics: "Null",
    completionCondition: "",
    loopCardinality: "",
    extensionElements: [],
    async: []
  }); //默认配置，用来覆盖原始不存在的选项，避免报错
  const [loopInstanceForm, setLoopInstanceForm] = useState({});
  const [isShow, setIsShow] = useState(false);
  const dataRef = useRef({})
  const [form] = Form.useForm(null);

  const getElementLoop = (businessObject) => {
    let loopCharacteristics = "Null";
    if (!businessObject.loopCharacteristics) {
      setLoopInstanceForm({ loopCharacteristics });
      return setTimeout(() => form.resetFields(), 0);
    }
    if (businessObject.loopCharacteristics.$type === "bpmn:StandardLoopCharacteristics") {
      setLoopInstanceForm({ loopCharacteristics: "StandardLoop" })
      return setTimeout(() => form.resetFields(), 0);
    }
    if (businessObject.loopCharacteristics.isSequential) {
      loopCharacteristics = "SequentialMultiInstance"
    } else {
      loopCharacteristics = "ParallelMultiInstance"
    }


    ["asyncAfter", "asyncBefore", "exclusive"].map(item => {
      businessObject.loopCharacteristics[item] && defaultLoopInstanceForm.async.push(item);
      Reflect.deleteProperty(businessObject.loopCharacteristics, item);
    })
    if (defaultLoopInstanceForm.async.length) setIsShow(true);

    // 合并配置
    const loopInstanceForm = {
      ...defaultLoopInstanceForm,
      ...businessObject.loopCharacteristics,
      loopCharacteristics,
      completionCondition: businessObject.loopCharacteristics?.completionCondition?.body ?? "",
      loopCardinality: businessObject.loopCharacteristics?.loopCardinality?.body ?? ""
    };

    // 保留当前元素 businessObject 上的 loopCharacteristics 实例
    dataRef.current.multiLoopInstance = dataRef.current.bpmnElement.businessObject.loopCharacteristics;
    // 更新表单
    if (businessObject.loopCharacteristics?.extensionElements?.values?.length) {
      setLoopInstanceForm({ ...loopInstanceForm, "timeCycle": businessObject.loopCharacteristics.extensionElements.values[0].body })
    }
    else {
      setLoopInstanceForm(loopInstanceForm)
    }
    setTimeout(() => form.resetFields(), 0);
  }

  // 回路特性
  const changeLoopCharacteristicsType = (type) => {
    // this.loopInstanceForm = { ...this.defaultLoopInstanceForm }; // 切换类型取消原表单配置
    // 取消多实例配置
    if (type === "Null") {
      window.bpmnInstances.modeling.updateProperties(dataRef.current.bpmnElement, { loopCharacteristics: null });
      return;
    }
    // 配置循环
    if (type === "StandardLoop") {
      const loopCharacteristicsObject = window.bpmnInstances.moddle.create("bpmn:StandardLoopCharacteristics");
      window.bpmnInstances.modeling.updateProperties(dataRef.current.bpmnElement, {
        loopCharacteristics: loopCharacteristicsObject
      });
      dataRef.current.multiLoopInstance = null;
      return;
    }
    // 时序
    if (type === "SequentialMultiInstance") {
      dataRef.current.multiLoopInstance = window.bpmnInstances.moddle.create("bpmn:MultiInstanceLoopCharacteristics", {
        isSequential: true
      });
    } else {
      dataRef.current.multiLoopInstance = window.bpmnInstances.moddle.create("bpmn:MultiInstanceLoopCharacteristics");
    }
    window.bpmnInstances.modeling.updateProperties(dataRef.current.bpmnElement, {
      loopCharacteristics: dataRef.current.multiLoopInstance
    });
  }

  // 循环基数
  const updateLoopCardinality = (cardinality) => {
    let loopCardinality = null;
    if (cardinality && cardinality.length) {
      loopCardinality = window.bpmnInstances.moddle.create("bpmn:FormalExpression", { body: cardinality });
    }
    window.bpmnInstances.modeling.updateModdleProperties(dataRef.current.bpmnElement, dataRef.current.multiLoopInstance, {
      loopCardinality
    });
  }

  // 直接更新的基础信息
  const updateLoopBase = () => {
    const collection = form.getFieldValue("collection")
    const elementVariable = form.getFieldValue("elementVariable")
    window.bpmnInstances.modeling.updateModdleProperties(dataRef.current.bpmnElement, dataRef.current.multiLoopInstance, {
      collection: collection || null,
      elementVariable: elementVariable || null
    });
  }

  // 完成条件
  const updateLoopCondition = (condition) => {
    let completionCondition = null;
    if (condition && condition.length) {
      completionCondition = window.bpmnInstances.moddle.create("bpmn:FormalExpression", { body: condition });
    }
    window.bpmnInstances.modeling.updateModdleProperties(dataRef.current.bpmnElement, dataRef.current.multiLoopInstance, {
      completionCondition
    });
  }

  // 各异步状态
  const updateLoopAsync = (checkedValue) => {
    let asyncAttr = Object.create(null);
    if (!checkedValue.includes("asyncBefore") && !checkedValue.includes("asyncAfter")) {
      asyncAttr = { asyncBefore: false, asyncAfter: false, exclusive: false, extensionElements: null };
    }
    else {
      asyncAttr = { asyncBefore: false, asyncAfter: false, exclusive: false }
      checkedValue.map(item => asyncAttr[item] = true);
    }
    setIsShow(checkedValue.includes("asyncBefore") || checkedValue.includes("asyncAfter"))
    window.bpmnInstances.modeling.updateModdleProperties(dataRef.current.bpmnElement, dataRef.current.multiLoopInstance, asyncAttr);
  }

  // 重试周期
  const updateLoopTimeCycle = (timeCycle) => {
    const extensionElements = window.bpmnInstances.moddle.create("bpmn:ExtensionElements", {
      values: [
        window.bpmnInstances.moddle.create(`${prefix}:FailedJobRetryTimeCycle`, {
          body: timeCycle
        })
      ]
    });
    window.bpmnInstances.modeling.updateModdleProperties(dataRef.current.bpmnElement, dataRef.current.multiLoopInstance, {
      extensionElements
    });
  }

  useEffect(() => {
    dataRef.current.bpmnElement = window.bpmnInstances.bpmnElement;
    getElementLoop(businessObject);
    return () => {
      dataRef.current.multiLoopInstance = null;
      dataRef.current.bpmnElement = null;
    }
  }, [businessObject])


  return <div className={styles.multiInstance}>
    <Form {...layout} form={form} initialValues={loopInstanceForm} name="multiInstance">
      <Form.Item name="loopCharacteristics" label="回路特性" >
        <Select allowClear
          onChange={changeLoopCharacteristicsType}>
          {/* bpmn:MultiInstanceLoopCharacteristics */}
          <Option value={"ParallelMultiInstance"}>并行多重事件</Option>
          <Option value={"SequentialMultiInstance"}>时序多重事件</Option>
          {/* bpmn:StandardLoopCharacteristics */}
          <Option value={"StandardLoop"}>循环事件</Option>
          <Option value={"Null"}>无</Option>
        </Select>
      </Form.Item>

      <Form.Item noStyle
        shouldUpdate={(prevValues, currentValues) => prevValues.loopCharacteristics !== currentValues.loopCharacteristics}
      >
        {({ getFieldValue }) => {
          const loopCharacteristics = getFieldValue('loopCharacteristics');
          switch (loopCharacteristics) {
            case 'ParallelMultiInstance':
            case 'SequentialMultiInstance':

              return <React.Fragment>
                <Form.Item name="loopCardinality" label="循环基数" >
                  <Input allowClear onChange={e => updateLoopCardinality(e.target.value)} />
                </Form.Item>
                <Form.Item name="collection" label="集合" onChange={e => updateLoopBase()}>
                  <Input allowClear />
                </Form.Item>
                <Form.Item name="elementVariable" label="元素变量" >
                  <Input allowClear onChange={e => updateLoopBase()} />
                </Form.Item>
                <Form.Item name="completionCondition" label="完成条件" >
                  <Input allowClear onChange={e => updateLoopCondition(e.target.value)} />
                </Form.Item>
                <Form.Item name="async" label="异步状态" style={{ height: "32px", lineHeight: "32px" }}>
                  <Checkbox.Group options={getOption(isShow)} onChange={updateLoopAsync} />
                </Form.Item>
                <Form.Item noStyle
                  shouldUpdate={(prevValues, currentValues) => prevValues.async !== currentValues.async}  >
                  {({ getFieldValue }) => {
                    const async = getFieldValue("async") || [];
                    return async.includes("asyncBefore") || async.includes("asyncAfter")
                      ? <Form.Item name="timeCycle" label="重试周期" >
                        <Input allowClear onChange={e => updateLoopTimeCycle(e.target.value)} />
                      </Form.Item>
                      : null
                  }}
                </Form.Item>
              </React.Fragment>

            default:
              return null
          }
        }}
      </Form.Item>
    </Form>
  </div >
};
export default Index;